#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from lxml import etree
import logging
# import traceback
from analyze.analyzer import BasicAnalyzer
from public.util import run_status
from basic.xpath_extractor import ElementExtractor


# 带解析器的下载器， 一般用于返回是html内容
def decode_response(response):
    if response.apparent_encoding is not None and response.apparent_encoding != 'utf-8':
        content = response.content.decode(response.apparent_encoding, 'replace')
    elif response.encoding != 'utf-8':
        content = response.content.decode('utf-8')
    else:
        content = response.text
    return content


class XpathAnalyzer(BasicAnalyzer):
    def __init__(self, config):
        self.mdb = config['mdb']
        self.name = config.get('analyze_type', config['name'].replace('download', 'analyze'))
        self.analyzer = ElementExtractor(self.name, self.mdb)

    def check(self, extra=None):
        ok_seq, msg = self.analyzer.check_element(extra)
        if len(msg) != 0:
            logging.warning('check failed {0}'.format(msg))
            return ok_seq, False
        return ok_seq, True

    def parse(self, response, task, extra=None):
        # 常见解码
        content = decode_response(response)

        # xpath选择器
        selector = etree.HTML(content, parser=etree.HTMLParser(encoding='utf-8'))
        ok_seq, ok_flag = self.check(selector)
        if not ok_flag:
            logging.error(response.text)
            return run_status['fail'], {}

        # 检验通过，需要写文件的写文件
        if 'file' in task:
            with open(task['file'], 'w', encoding='utf-8') as fp:
                fp.write(content)

        # 根据数据库配置规则解析提取元素
        elements = self.analyzer.get_html_element(selector, task, ok_seq)
        # 根据自定义的规则提取元素并合并
        personals = self.personal(selector, task)
        for k, v in personals.items():
            # 自定义优先级高于rule
            elements[k] = v
        return run_status['success'], elements

    # 定义一些规则配置实现不了的，比如保存html段落
    def personal(self, selector, task):
        # 单纯的为了通过pycharm语法规范检测，没啥用
        if hasattr(self, 'nothing') or selector is None or task is None:
            pass
        return {}
